/*
	MIDAS Context Based Routing
	cbr_crtable.h
	Copyright (c) 2007 Radoslaw Olgierd Schoeneich
	MEAG IT PW
*/

#ifndef cbr_crtable_h_
#define cbr_crtable_h_

#include <list>
#include <utility>

#include "cbr_types.h"
#include "cbr_triple.h"

/**
 * Context Routing Table entry.
 */

class cbr_Route : private cbr_Object {
private:
	cbr_Concept		concept;
	double			expire;	// ALLOWED_HELLO_LOSS * HELLO_INTERVAL

	cbr_ID			source;
	cbr_ID			forwarder;
	int			hop_count;

public:
	cbr_Route(const cbr_Triple& triple, cbr_ID forwarder);

	cbr_Triple*	getAsTriple() const;
	cbr_Concept	getConcept() const { return concept; }
	cbr_ID		getSource() const { return source; }
	cbr_ID		getForwarder() const { return forwarder; }
	int		getMetric() const { return hop_count; }

	bool		update(const cbr_Triple& triple, cbr_ID forwarder);
	double		expires() const { return expire; }

	bool		matches(const cbr_Concept& c) const
	{
		return (this->concept == c);
	}
};

/**
 * Context Routing Table.
 */

class cbr_CRTable : private cbr_Object {
private:
	typedef std::list<cbr_Route*> routes_list;
	routes_list routes;

public:
	cbr_CRTable();
	~cbr_CRTable();

	cbr_TriplesList	getAsTriples() const;

	void		update(const cbr_Triple& triple, cbr_ID forwarder);
	void		purge();

	cbr_ConceptsSet getConcepts(void) const;
	bool		match(cbr_ConceptsSet &cset) const;

	bool		getForwarders(const cbr_Concept& concept,
				std::list< std::pair<cbr_ID, int> >& fl,
				cbr_ID localID) const;

	bool		getForwarders(cbr_ID id,
				std::list< std::pair<cbr_ID, int> >& fl,
				cbr_ID localID) const;

	bool		getSources(const cbr_Concept& concept,
				std::list< std::pair<cbr_ID, int> >& sl,
				cbr_ID localID) const;
};

#endif	// cbr_crtable_h_
